{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# USAD-LSTM在SMD数据集上实验"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/user/miniconda3/envs/yjq-ml/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.metrics import roc_auc_score\n",
    "import numpy as np\n",
    "import os\n",
    "import pickle\n",
    "\n",
    "from torch.utils.data import DataLoader\n",
    "from torch.utils.data.sampler import SubsetRandomSampler\n",
    "import torch\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import torch.nn as nn\n",
    "\n",
    "from usadlstm_model import  *\n",
    "import sys\n",
    "sys.path.append('../common/')\n",
    "from evaluator import *\n",
    "from utils import *\n",
    "from datasets import MonitorEntityDataset_SMD\n",
    "import pickle as pk\n",
    "import IPython\n",
    "import random\n",
    "\n",
    "gpu_choice =get_default_device().index"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 读数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_prefix = '../data/SMD/train/'\n",
    "test_prefix = '../data/SMD/test/'\n",
    "label_prefix = '../data/SMD/labels/'\n",
    "\n",
    "trainfiles = [train_prefix + f for f in sorted(os.listdir(train_prefix))]\n",
    "\n",
    "# trainfiles = trainfiles[:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "testfiles = [test_prefix + f for f in sorted(os.listdir(test_prefix))]\n",
    "len(trainfiles) == len(testfiles)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "lr=1e-4\n",
    "num_epochs=5\n",
    "window_size = 5\n",
    "z_dim = 38\n",
    "batch_size = 1024\n",
    "\n",
    "dataset_name = \"SMD\"\n",
    "general_path = \"%s-batch-%s-epochs-%s-hidden-%s\" %(dataset_name, batch_size, num_epochs, z_dim)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 预处理标准化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 36.6 s, sys: 2.95 s, total: 39.5 s\n",
      "Wall time: 32.8 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "dataset = MonitorEntityDataset_SMD(trainfiles, testfiles, window_size, z_dim, gpu=gpu_choice)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_gaussian_percentage = 0.2\n",
    "mac_ids = testfiles\n",
    "results = {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "../data/SMD/test/machine-3-9.txt\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "  0%|          | 0/5 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 5/5 [00:52<00:00, 10.54s/it]\n"
     ]
    }
   ],
   "source": [
    "for i in range(len(mac_ids)):\n",
    "    IPython.display.clear_output()\n",
    "\n",
    "    print(mac_ids[i])\n",
    "    \n",
    "    dataset.train(mac_ids[i])\n",
    "    model = UsadLSTM(dataset[0].shape[0], z_dim)\n",
    "    model.to(get_default_device())\n",
    "\n",
    "    sequences = dataset\n",
    "\n",
    "    indices = np.random.permutation(len(sequences))\n",
    "    split_point = int(train_gaussian_percentage * len(sequences))\n",
    "    train_loader = DataLoader(dataset=sequences, batch_size=batch_size, drop_last=True,\n",
    "                              sampler=SubsetRandomSampler(indices[:-split_point]), pin_memory=False)\n",
    "    val_loader = DataLoader(dataset=sequences, batch_size=batch_size, drop_last=True,\n",
    "                                       sampler=SubsetRandomSampler(indices[-split_point:]), pin_memory=False)\n",
    "    \n",
    "    history = model.fit(\n",
    "        train_loader=train_loader,\n",
    "        validation_loader=val_loader,\n",
    "        epochs=num_epochs\n",
    "    )\n",
    "    model_path =  \"../model/USAD-LSTM/\" + general_path + str(i) +  \".pth\"\n",
    "    torch.save({\n",
    "    'encoder': model.encoder.state_dict(),\n",
    "    'decoder1': model.decoder1.state_dict(),\n",
    "    'decoder2': model.decoder2.state_dict()\n",
    "    }, model_path)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(len(mac_ids)):\n",
    "    dataset.test(mac_ids[i])\n",
    "\n",
    "    model = UsadLSTM(dataset[0].shape[0], z_dim)\n",
    "    model_path =  \"../model/USAD-LSTM/\" + general_path + str(i) +  \".pth\"\n",
    "    checkpoint = torch.load(model_path, map_location=get_default_device())\n",
    "    model.encoder.load_state_dict(checkpoint['encoder'])\n",
    "    model.decoder1.load_state_dict(checkpoint['decoder1'])\n",
    "    model.decoder2.load_state_dict(checkpoint['decoder2'])\n",
    "    model.to(get_default_device())\n",
    "    \n",
    "    test_loader = DataLoader(dataset=dataset, batch_size=batch_size, shuffle=False, drop_last=False)\n",
    "\n",
    "    label = pd.read_csv(label_prefix+mac_ids[i].split('/')[-1], header=None)\n",
    "    label = label.values.flatten()\n",
    "\n",
    "    pred= model.predict_prob(test_loader, alpha=0.3, beta=0.7)\n",
    "\n",
    "    results[mac_ids[i]] = bf_search(label.flatten(), pred, verbose=False)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "precision mean: 0.8962\n",
      "recall mean: 0.9235\n",
      "f1 mean: 0.8978\n",
      "f1* mean: 0.9096\n"
     ]
    }
   ],
   "source": [
    "f1_scores = [item['f1-score'] for item in list(results.values())]\n",
    "precisions = [item['precision'] for item in list(results.values())]\n",
    "recalls = [item['recall'] for item in list(results.values())]\n",
    "TNs = [item['TN'] for item in list(results.values())]\n",
    "TPs = [item['TP'] for item in list(results.values())]\n",
    "FNs = [item['FN'] for item in list(results.values())]\n",
    "FPs = [item['FP'] for item in list(results.values())]\n",
    "f1_mean = round(np.mean(f1_scores).item(),4)\n",
    "precision_mean = round(np.mean(precisions),4)\n",
    "recall_mean = round(np.mean(recalls),4)\n",
    "f1_star = round(2 * precision_mean * recall_mean / (precision_mean + recall_mean + 0.00001),4)\n",
    "print(f\"precision mean: {precision_mean}\")\n",
    "print(f\"recall mean: {recall_mean}\")\n",
    "print(f\"f1 mean: {f1_mean}\")\n",
    "print(f\"f1* mean: {f1_star}\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
